import { message, Modal } from 'antd'
import { Http } from '../../Api'
import ReactDOM from 'react-dom'
import { useEventEmitter, useRequest, useSetState } from 'ahooks'
import { useState, useRef, useEffect } from 'react'
import { Initialization, drawBoundWall, drawBoundPolygon, drawBoundMask, drawBoundStroke } from './Mars3d'
import {
    Mars3DNavOne,
    Mars3DNavTwo,
    NavTwoTemplate,
    SceneAnalogData,
    LayerAnalogData,
    SceneOptions,
    GlobeOptions,
    CameraOptions,
    SceneSkyBoxData,
    CustomizeNavigation,
    SystemComponents,
} from './Data'

const { Cesium, mars3d } = window

export const Mars3dBox = ({ uuid, Off }) => {
    const [SceneBasicConfig, setSceneBasicConfig] = useSetState({})
    const [LayerConfiguration, setLayerConfiguration] = useSetState({})
    const { runAsync: getSceneBasicConfigs } = useRequest(Http, { manual: true })
    const { runAsync: posSceneBasicConfigs } = useRequest(Http, { manual: true })
    const { runAsync: putSceneBasicConfigs } = useRequest(Http, { manual: true })
    const [Map, setMap] = useState()
    const [Gra, setGra] = useState()
    // Mars3D 需请求的接口列表
    useEffect(() => {
        // *** 判断uuid的配置参数
        // ? 有值加载参数配置值
        // ? 空创建默认参数值   使用 AnalogData
        // *** 更新Data数据

        // 加载基础数据
        getSceneBasicConfigs({ url: 'getSceneBasicConfigs', data: { sceneInfoUuid: uuid } }).then(({ total, list }) => {
            if (total && total !== 0) {
                const [SceneData] = list
                setSceneBasicConfig(SceneData)
                setLayerConfiguration(LayerAnalogData)
                InitializationData({ Scene: SceneData, Layer: LayerAnalogData })
            } else {
                let data = SceneAnalogData
                data.sceneInfoUuid = uuid
                posSceneBasicConfigs({ url: 'posSceneBasicConfigs', data }).then(() => {
                    setSceneBasicConfig(SceneAnalogData)
                    setLayerConfiguration(LayerAnalogData)
                    InitializationData({ Scene: SceneAnalogData, Layer: LayerAnalogData })
                })
            }
        })
    }, [setLayerConfiguration, setSceneBasicConfig, getSceneBasicConfigs, posSceneBasicConfigs, uuid])

    const InitializationData = ({ Scene, Layer = {} }) => {
        const { map, gra } = Initialization({ type: 'debugging', MapBox, Scene, Layer })
        setMap(map)
        setGra(gra)
    }

    // 场景参数配置
    const SceneEvent = useEventEmitter()
    SceneEvent.useSubscription(obj => {
        const [Key] = Object.keys(obj)
        const [Value] = Object.values(obj)
        const {
            fog,
            rain,
            snow,
            snowCover,
            outline,
            bloomTarget,
            bloom,
            brightness,
            nightVision,
            blackAndWhite,
            mosaic,
            depthOfField,
        } = Map.effects
        const KeySelect = {
            basemap: () => (Map.basemap = Value),
            basemaps: () => {
                if (Value) Map.basemap = SceneBasicConfig.basemap
                else Map.basemap = undefined
            },
            layer: () => {
                const layers = Map.getLayers({ basemaps: false, layers: true })
                layers.forEach(key => {
                    if (!Value.includes(key.id)) Map.removeLayer(key)
                    else Map.addLayer(key)
                })
            },
            sceneSkyBox: () => {
                if (Value < 7) Map.scene.skyBox = new Cesium.SkyBox(SceneSkyBoxData[Value])
                else Map.scene.skyBox = new mars3d.GroundSkyBox(SceneSkyBoxData[Value])
            },
            fogEffect: () => (fog.enabled = Value),
            rainEffect: () => (rain.enabled = Value),
            snowEffect: () => (snow.enabled = Value),
            snowCover: () => (snowCover.enabled = Value),
            outlineEffect: () => (outline.enabled = Value),
            bloomTargetEffect: () => (bloomTarget.enabled = Value),
            bloomEffect: () => (bloom.enabled = Value),
            brightnessEffect: () => (brightness.enabled = Value),
            nightVisionEffect: () => (nightVision.enabled = Value),
            blackAndWhiteEffect: () => (blackAndWhite.enabled = Value),
            mosaicEffect: () => (mosaic.enabled = Value),
            depthOfField: () => (depthOfField.enabled = Value),
            submitScene: () =>
                putSceneBasicConfigs({
                    url: 'putSceneBasicConfigs',
                    data: SceneBasicConfig,
                    path: [SceneBasicConfig.uuid],
                }).then(() => message.success('基础场景保存成功')),
        }

        // 场景配置
        if (SceneOptions.includes(Key)) Map.setSceneOptions(obj)
        else if (GlobeOptions.includes(Key)) Map.setSceneOptions({ globe: { ...obj } })
        else if (CameraOptions.includes(Key)) {
            Map.setSceneOptions({ cameraController: { ...obj } })
            if (Key === 'constrainedAxis' && Value === true) Map.camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z
        } else if (CustomizeNavigation.includes(Key)) {
            const DOM = document.getElementById(Key)
            ReactDOM.findDOMNode(DOM).style.display = Value ? 'inline-block' : 'none'
        } else if (SystemComponents.includes(Key)) Map.controls[Key].show = Value
        else KeySelect[Key]()

        setSceneBasicConfig(obj)
    })

    // 图层基础配置
    const LayerEvent = useEventEmitter()
    LayerEvent.useSubscription(obj => {
        const [Key] = Object.keys(obj)
        const [Value] = Object.values(obj)
        const boundWall = Map.getLayerById('boundWall')
        const boundStroke = Map.getLayerById('boundStroke')
        const boundPolygon = Map.getLayerById('boundPolygon')
        const boundMask = Map.getLayerById('boundMask')

        const {
            boundData,
            maskState,
            maskColor,
            polygonStart,
            polygonColor,
            strokeState,
            strokeColor,
            strokeWidth,
            strokeText,
            strokeTextColor,
            wallState,
            wallColor,
            wallHeight,
        } = LayerConfiguration

        const KeySelect = {
            // 加载数据
            boundData: () => {
                Map.removeLayer(boundWall)
                Map.removeLayer(boundStroke)
                Map.removeLayer(boundPolygon)
                Map.removeLayer(boundMask)
                drawBoundWall({ Map, name: Value, state: wallState, color: wallColor, height: wallHeight })
                drawBoundStroke({
                    Map,
                    name: Value,
                    state: strokeState,
                    color: strokeColor,
                    width: strokeWidth,
                    text: strokeText,
                    textColor: strokeTextColor,
                })
                drawBoundPolygon({ Map, name: Value, state: polygonStart, color: polygonColor })
                drawBoundMask({ Map, name: Value, state: maskState, color: maskColor })
            },
            // 边界墙
            wallState: () => {
                if (boundWall) boundWall.show = Value
            },
            wallColor: () => {
                Map.removeLayer(boundWall)
                drawBoundWall({ Map, name: boundData, state: wallState, color: Value, height: wallHeight })
            },
            wallHeight: () => {
                Map.removeLayer(boundWall)
                drawBoundWall({ Map, name: boundData, state: wallState, color: wallColor, height: Value })
            },
            // 内描边
            strokeState: () => {
                if (boundStroke) boundStroke.show = Value
            },
            strokeWidth: () => {
                Map.removeLayer(boundStroke)
                drawBoundStroke({
                    Map,
                    name: boundData,
                    state: strokeState,
                    color: strokeColor,
                    width: Value,
                    text: strokeText,
                    textColor: strokeTextColor,
                })
            },
            strokeColor: () => {
                Map.removeLayer(boundStroke)
                drawBoundStroke({
                    Map,
                    name: boundData,
                    state: strokeState,
                    color: Value,
                    width: strokeWidth,
                    text: strokeText,
                    textColor: strokeTextColor,
                })
            },
            strokeText: () => {
                Map.removeLayer(boundStroke)
                drawBoundStroke({
                    Map,
                    name: boundData,
                    state: strokeState,
                    color: strokeColor,
                    width: strokeWidth,
                    text: Value,
                    textColor: strokeTextColor,
                })
            },
            strokeTextColor: () => {
                Map.removeLayer(boundStroke)
                drawBoundStroke({
                    Map,
                    name: boundData,
                    state: strokeState,
                    color: strokeColor,
                    width: strokeWidth,
                    text: strokeText,
                    textColor: Value,
                })
            },
            // 面状态
            polygonStart: () => {
                if (boundPolygon) boundPolygon.show = Value
            },
            polygonColor: () => {
                Map.removeLayer(boundPolygon)
                drawBoundPolygon({ Map, name: boundData, state: polygonStart, color: Value })
            },
            // 遮罩层
            maskState: () => {
                if (boundMask) boundMask.show = Value
            },
            maskColor: () => {
                Map.removeLayer(boundMask)
                drawBoundMask({ Map, name: boundData, state: maskState, color: Value })
            },

            // 独立图层
            different: () => {
                console.log(Value)
            },
        }

        KeySelect[Key]()
        setLayerConfiguration(obj)
    })

    const MapBox = useRef()
    const [NavActive, setNavActive] = useState('scene')
    const [NavTwoActive, setNavTwoActive] = useState()

    const NavClick = uuid => {
        setNavTwoActive()
        setNavActive(uuid)
    }

    return (
        <Modal
            className="Mars3DSceneModal"
            open={true}
            footer={null}
            maskClosable={false}
            onCancel={Off}
            destroyOnClose
            width={`95vw`}
        >
            <div className="Title" style={{ background: 'var(--DominantDark)' }}>
                <div className="title">场景明细</div>
                <div className="nav">
                    {Mars3DNavOne.map(({ uuid, title }) => (
                        <div key={uuid} className={NavActive === uuid ? 'active' : ''} onClick={() => NavClick(uuid)}>
                            {title}
                        </div>
                    ))}
                </div>
            </div>
            <div className="MapBox">
                <div className="Map" ref={MapBox} />
                <div className="NavTwo">
                    {Object.keys(Mars3DNavTwo[NavActive]).map(key => (
                        <div onClick={() => setNavTwoActive(key)} key={key}>
                            {Mars3DNavTwo[NavActive][key]}
                        </div>
                    ))}
                </div>

                {/* 弹出二级控件 */}
                {NavTwoActive &&
                    (() => {
                        const Template = NavTwoTemplate[NavTwoActive]
                        return (
                            <Template
                                Map={Map}
                                Gra={Gra}
                                Scene={SceneBasicConfig}
                                SceneEvent={SceneEvent}
                                Layer={LayerConfiguration}
                                LayerEvent={LayerEvent}
                            />
                        )
                    })()}
            </div>
        </Modal>
    )
}
